import json
import os
import re
from pathlib import Path

class DataManager:
    def __init__(self, save_root='save', data_root='data'):
        self.save_root = save_root
        self.data_root = data_root
        self.themes = self.read_theme_file()

    def save_game(self, game_state):
        """Save game data to a file."""
        data = self.try_load_game()

        if game_state.mode == 'endless':
            data['game'] = {
                'encrypted_text': game_state.puzzle.encrypted_text,
                'decrypted_text': game_state.puzzle.decrypted_text,
                'quote': game_state.puzzle.quote,
                'key': game_state.puzzle.key,
                'letter_mappings': game_state.puzzle.letter_mappings
            }
        elif game_state.mode == 'story':
            if 'story_mode' not in data:
                data['story_mode'] = {}
            if game_state.puzzle is None:
                current_game = None
            else:
                current_game = {
                    'encrypted_text': game_state.puzzle.encrypted_text,
                    'decrypted_text': game_state.puzzle.decrypted_text,
                    'quote': game_state.puzzle.quote,
                    'key': game_state.puzzle.key,
                    'letter_mappings': game_state.puzzle.letter_mappings
                }

            data['story_mode'][game_state.story['id']] = {
                'level': game_state.level['id'],
                'level_history': game_state.level_history,
                'current_game': current_game
            }

        data['user_preferences'] = {
            'visual_theme': game_state.user_preferences.visual_theme,
            'quote_db': game_state.user_preferences.quote_db
        }

        if not os.path.exists(self.save_root):
            os.makedirs(self.save_root, exist_ok=True)  # Ensure the directory exists

        with open(self.save_root + '/game_data.json', "w") as f:
            json.dump(data, f)

    def try_load_game(self):
        """Load game data from a file."""
        try:
            with open(self.save_root + '/game_data.json', "r") as f:
                return json.load(f)
        except FileNotFoundError:
            return {}

    def get_theme(self, theme_id):
        return next((theme for theme in self.themes if theme["id"] == theme_id), None)

    def read_theme_file(self):
        file_path = 'themes.json'
        try:
            with open(self.data_root + '/' + file_path, "r", encoding="utf-8") as file:
                data = json.load(file)
                return data
        except FileNotFoundError:
            return []

    def list_quote_dbs(self):
        file_path = self.data_root + '/fortunes/'
        path = Path(file_path)
        files = [f.name for f in path.iterdir() if f.is_file()]
        return sorted(files)

    def list_stories(self):
        file_path = 'stories.json'
        try:
            with open(self.data_root + '/' + file_path, "r", encoding="utf-8") as file:
                data = json.load(file)
                return data
        except FileNotFoundError:
            return []

    def read_quote_db(self, db_name):
        file_path = 'fortunes/' + db_name
        try:
            with open(self.data_root + '/' + file_path, "r", encoding="utf-8") as file:
                file_content = file.read()
        except FileNotFoundError:
            return []

        fortunes = []
        entries = file_content.strip().split("%")

        for entry in entries:
            source_quote_list = entry.strip().split("\n\t\t-- ")
            if (len(source_quote_list) == 1):
                quote = source_quote_list[0].strip()
                if (len(quote) > 2):
                    fortunes.append({"quote": quote})
            elif (len(source_quote_list) == 2):
                quote = source_quote_list[0].strip()
                source = source_quote_list[1].strip()
                if (len(quote) > 2 and len(source) > 2):
                    fortunes.append({"quote": quote, "source": source})

        filtered_fortunes = [
            fortune for fortune in fortunes
            if all(len(line) >= 60 for line in fortune["quote"].split("\n"))
        ]

        return filtered_fortunes
